package threedee.generator;

import processing.core.PGraphics;
import processing.core.PImage;

public class RoadBlock extends AbstractBlock{

	private BlockType type; // Block type
	private int rotation;
	
	
	public RoadBlock(){
		this.type = BlockType.STRAIGHT_ROAD;
	}
	
	//constructor gets arguments as to where there are open areas
	public RoadBlock(boolean north, boolean south, boolean west, boolean east){
		
		this.type = BlockType.DUMMY_ROAD;
		
		//everything is open
		if (north && south && west && east) {
			this.type = BlockType.X_CROSSING_ROAD;
			this.rotation = 0;
		
			//0 rotation is north blocked, i.e. facing down, "T"
		} else if (north && south && west && !east){
			this.type = BlockType.T_CROSSING_ROAD;
			this.rotation = 90;
		} else if (north && south && !west && east){
			this.type = BlockType.T_CROSSING_ROAD;
			this.rotation = 270;
		} else if (north && !south && west && east){
			this.type = BlockType.T_CROSSING_ROAD;
			this.rotation = 180;
		} else if (!north && south && west && east){
			this.type = BlockType.T_CROSSING_ROAD;
			this.rotation = 0;
			// 0 rotation is north and south blocked, or -
		} else if (!north && !south && west && east){
			this.type = BlockType.STRAIGHT_ROAD;
			this.rotation = 0;
		} else if (north && south && !west && !east){
			this.type = BlockType.STRAIGHT_ROAD;
			this.rotation = 90;
			
			//again, 0 rotation is -
		} else if (!north && !south && !west && east){
			this.type = BlockType.STRAIGHT_ROAD;
			this.rotation = 0;
		} else if (!north && !south && west && !east){
			this.type = BlockType.STRAIGHT_ROAD;
			this.rotation = 0;
		} else if (north && !south && !west && !east){
			this.type = BlockType.STRAIGHT_ROAD;
			this.rotation = 90;
		} else if (!north && south && !west && !east){
			this.type = BlockType.STRAIGHT_ROAD;
			this.rotation = 90;
			
			// 0 rotation is /
		} else if (!north && south && !west && east){
			this.type = BlockType.TURN_ROAD;
			this.rotation = 0;
		} else if (!north && south && west && !east){
			this.type = BlockType.TURN_ROAD;
			this.rotation = 90;
		} else if (north && !south && west && !east){
			this.type = BlockType.TURN_ROAD;
			this.rotation = 180;
		} else if (north && !south && !west && !east){
			this.type = BlockType.TURN_ROAD;
			this.rotation = 270;
		}
		
		
	}
	
	public int getRotation(){
		return this.rotation;
	}

	public void draw(PGraphics g, PImage[] texture, float x, float y) {
		g.pushMatrix();
		g.translate(x*BLOCK_SCALE-BLOCK_SCALE/2, y*BLOCK_SCALE-BLOCK_SCALE/2, 0);
		this.drawRoadblock(g, texture, this.type);
		g.popMatrix();
	}

	private void drawRoadblock(PGraphics g, PImage[] texture, BlockType b){
		switch (b) {
		case STRAIGHT_ROAD: if (this.rotation == 0){
			this.drawStraight(g, texture[4], texture[5]); break;
		} else {
			g.pushMatrix();
			g.translate(BLOCK_SCALE/2, BLOCK_SCALE/2, 0);
			g.pushMatrix();
			g.rotate((float) (Math.PI/2));
			g.translate(-BLOCK_SCALE/2, -BLOCK_SCALE/2, 0);
			this.drawStraight(g, texture[4], texture[5]);
			g.popMatrix();
			g.popMatrix();
			break;
		}
			
		case X_CROSSING_ROAD: this.drawXCrossing(g, texture[4], texture[5]); break;
		
		case T_CROSSING_ROAD: 
			g.pushMatrix();
			g.translate(BLOCK_SCALE/2, BLOCK_SCALE/2, 0);
			g.pushMatrix();
			g.rotate((float) (-this.rotation/180*Math.PI + Math.PI));
			g.translate(-BLOCK_SCALE/2, -BLOCK_SCALE/2, 0);
			this.drawTCrossing(g, texture[4], texture[5]);
			g.popMatrix();
			g.popMatrix();
			break;
			
		case TURN_ROAD: 
			g.pushMatrix();
			g.translate(BLOCK_SCALE/2, BLOCK_SCALE/2, 0);
			g.pushMatrix();
			g.rotate((float) (this.rotation/180*Math.PI + Math.PI));
			g.translate(-BLOCK_SCALE/2, -BLOCK_SCALE/2, 0);
			this.drawTCrossing(g, texture[4], texture[5]);
			g.popMatrix();
			g.popMatrix();
			break;
		}
	}
	
	//draws straight piece
	
	private void drawStraight(PGraphics g, PImage textureSide, PImage textureTop) {
		
		int uSide = textureSide.width;
		int vSide = textureSide.height;
		int uTop = textureTop.width;
		int vTop = textureTop.width;
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE/6, 0, 0, uSide, 0);
		g.vertex(BLOCK_SCALE/6, 0, BLOCK_SCALE/10, uSide, vSide);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE, 0, 0, vSide);
		g.endShape();
		
		g.beginShape();
		g.texture(textureTop);
		g.vertex(BLOCK_SCALE/6, 0, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE, BLOCK_SCALE/10, uTop, 0);
		g.vertex(0, BLOCK_SCALE, BLOCK_SCALE/10, 0, vTop);
		g.vertex(0, 0, BLOCK_SCALE/10, uTop, vTop);
		g.endShape();
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE*5/6, 0, 0, 0, vSide);
		g.vertex(BLOCK_SCALE*5/6, 0, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE, BLOCK_SCALE/10, uSide, vSide);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE, 0, uSide, 0);
		g.endShape();
		
		g.beginShape();
		g.texture(textureTop);
		g.vertex(BLOCK_SCALE*5/6, 0, BLOCK_SCALE/10, 0, vTop);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE, BLOCK_SCALE/10, uTop, vTop);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE, 0, BLOCK_SCALE/10, uTop, 0);
		g.endShape();
	}
	
	private void drawTCrossing(PGraphics g, PImage textureSide, PImage textureTop) {
		int u = textureTop.width;
		int v = textureTop.height;
		
		//eka pala
		g.beginShape();
		g.texture(textureSide);
		g.vertex(0, BLOCK_SCALE/6, 0, 0, v);
		g.vertex(0, BLOCK_SCALE/6, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE/6, 0, u, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureTop);
		g.vertex(0, BLOCK_SCALE/6, BLOCK_SCALE/10, 0, v);
		g.vertex(0, 0, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE, 0, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE/6, BLOCK_SCALE/10, u, v);
		g.endShape();
		
		//toka pala
		g.beginShape();
		g.texture(textureSide);
		g.vertex(0, BLOCK_SCALE*5/6, 0, u, v);
		g.vertex(0, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE*5/6, 0, 0, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE*5/6, 0, u, v);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE, 0, 0, v);
		g.endShape();
		
		
		g.beginShape();
		g.texture(textureTop);
		g.vertex(0, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, v);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE, BLOCK_SCALE/10, 0, v);
		g.vertex(0, BLOCK_SCALE, BLOCK_SCALE/10, 0, 0);
		g.endShape();
		
		//kolmas pala
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE*5/6, 0, u, v);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE*5/6, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE*5/6, 0, v, u);
		g.endShape();
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE*5/6, 0, 0, v);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE, 0, u, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureTop);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, 0, v);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE*5/6, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE, BLOCK_SCALE/10, u, v);
		g.endShape();
	}
	
	
	private void drawXCrossing(PGraphics g, PImage textureSide, PImage textureTop) {
		
		int u = 0;
		int v = 0;
		//x road
		g.beginShape();
		g.texture(textureSide);
		g.vertex(0, BLOCK_SCALE/6, 0, 0, v);
		g.vertex(0, BLOCK_SCALE/6, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE/6, 0, u, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE/6, 0, 0, 0, v);
		g.vertex(BLOCK_SCALE/6, 0, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE/6, 0, u, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureTop);
		g.vertex(0, 0, BLOCK_SCALE/10, 0, 0);
		g.vertex(0, BLOCK_SCALE/6, BLOCK_SCALE/10, 0, v);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE/6, BLOCK_SCALE/10, u, v);
		g.vertex(BLOCK_SCALE/6, 0, BLOCK_SCALE/10, u, 0);
		g.endShape();
		
		//2nd piece
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE*5/6, 0, 0, v);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE*5/6, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE*5/6, 0, u, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE, 0, 0, v);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE*5/6, 0, u, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureTop);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE*5/6, BLOCK_SCALE/10, 0, v);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, v);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE, BLOCK_SCALE/10, u, 0);
		g.endShape();
		
		//3rd piece
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE/6, 0, 0, v);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE/6, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE/6, 0, u, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE*5/6, 0, 0, 0, v);
		g.vertex(BLOCK_SCALE*5/6, 0, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE/6, 0, u, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureTop);
		g.vertex(BLOCK_SCALE, 0, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE, BLOCK_SCALE/6, BLOCK_SCALE/10, 0, v);
		g.vertex(BLOCK_SCALE*5/6, BLOCK_SCALE/6, BLOCK_SCALE/10, u, v);
		g.vertex(BLOCK_SCALE*5/6, 0, BLOCK_SCALE/10, u, 0);
		g.endShape();
	
		//4th piece
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(0, BLOCK_SCALE*5/6, 0, 0, v);
		g.vertex(0, BLOCK_SCALE*5/6, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE*5/6, 0, u, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureSide);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE, 0, 0, v);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE, BLOCK_SCALE/10, 0, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, 0);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE*5/6, 0, u, v);
		g.endShape();
		
		g.beginShape();
		g.texture(textureTop);
		g.vertex(0, BLOCK_SCALE, BLOCK_SCALE/10, 0, 0);
		g.vertex(0, BLOCK_SCALE*5/6, BLOCK_SCALE/10, 0, v);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE*5/6, BLOCK_SCALE/10, u, v);
		g.vertex(BLOCK_SCALE/6, BLOCK_SCALE, BLOCK_SCALE/10, u, 0);
		g.endShape();
	}
	@Override
	public BlockType getType() {
		return this.type;
	}
	
	public String toString(){
		return this.type.toString();
	}
	
	public String toString(int rotation){
		return this.type.toString(rotation);
	}

}
